package com.lbb.springbootstock.v2.service;


import com.alibaba.fastjson.JSONObject;
import com.lbb.springbootstock.client.HttpClient;
import com.lbb.springbootstock.client.JdbcUtil;
import com.lbb.springbootstock.v2.bean.KlineData;
import com.lbb.springbootstock.v2.bean.ResponseData;
import com.lbb.springbootstock.v2.bean.ResultData;
import com.lbb.springbootstock.v2.bean.StockBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author 黎兵兵
 */
@Component
public class StockService {
    @Autowired
    JavaMailSender mailSender;

    public void sendMessage(ArrayList<ResultData> resp) {
        resp.stream().sorted(new Comparator<ResultData>() {
            @Override
            public int compare(ResultData o1, ResultData o2) {
                double v = o2.getPrice() - o1.getPrice();
                return Integer.parseInt(v + "");
            }
        });
        SimpleMailMessage mailMessage = new SimpleMailMessage();
        StringBuffer sb = new StringBuffer();
        resp.stream().forEach(item -> {
            if(!item.getName().contains("ST")){
                sb.append(item.toString() + "\n");
            }
        });
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(new Date());
        mailMessage.setSubject(date + "日致富经");
        String bt = "代号 ----名称---股票收盘价--- 股票60日K线价--- 20日K线价"+"\n";
        mailMessage.setText(bt + sb.toString());
        String mail = JdbcUtil.getMail();
        String[] receivers = mail.split(",");
        mailMessage.setTo(receivers);
        mailMessage.setFrom("1587167182@qq.com");
        System.out.println("-------------------发送邮件完成-------------------");
        mailSender.send(mailMessage);
    }


    public void entrance() throws SQLException {
        ArrayList<StockBase> data = getData();
        List<StockBase> distinct = data.stream().distinct().collect(Collectors.toList());
        List<List<StockBase>> list = fixedGrouping2(distinct, 1000);
        ExecutorService pool = Executors.newFixedThreadPool(list.size());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        int hour = getHour(date);
        if (hour < 19) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            date = calendar.getTime();
        }
        for (int i = 0; i < list.size(); i++) {
            List<StockBase> stockBases = list.get(i);
            Date finalDate = date;
            int finalI = i;
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("任务" + finalI + "执行");
                    ArrayList<ResultData> resp = new ArrayList<>();
                    stockBases.forEach(item -> {
                        String fix = item.getFix();
                        String pre = item.getPre();
                        String name = item.getName();
                        String endTime = dateToTimestamp(simpleDateFormat.format(finalDate)) + "";
                        String url = "https://hq.chongnengjihua.com/rjhy-gmg-quote/api/1/stock/quote/v1/historyv1?endtime=" + endTime + "&inst=" + pre + "&limit=-1200&market=" + fix + "&servicetype=KLINEB&starttime=0&resptype=JSON&period=DAY";
                        String json = HttpClient.doGet(url);
                        ResponseData response = parse(json);
                        ArrayList<KlineData> data = response.getKlineData();
                        if (data.size() >= 60) {
                            Double sixValue = getSixValue(data);
                            Double towValue = getTowValue(data);
                            sort(data);
                            KlineData klineData = data.get(0);
                            if(Double.parseDouble(klineData.getClose())<60){
                                boolean flag = cal(Double.parseDouble(data.get(0).getClose()), sixValue);
                                if (flag) {
                                    System.out.println(response.getInst() + " √ ");
                                    ResultData resultData = new ResultData();
                                    resultData.setCode(response.getInst());
                                    resultData.setPrice(Double.parseDouble(klineData.getClose()));
                                    resultData.setV20(towValue);
                                    resultData.setV60(sixValue);
                                    resultData.setName(name);
                                    resp.add(resultData);
                            }
                            } else {
                                System.out.println(response.getInst() + " × ");
                            }
                        }
                    });

                    sendMessage(resp);
                    System.out.println("任务" + finalI + "执行结束");
                }
            });
            pool.shutdown();
        }
    }

    public int getHour(Date date) {
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        return instance.get(Calendar.HOUR_OF_DAY);
    }

    public long dateToTimestamp(String time) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = simpleDateFormat.parse(time);
            long ts = date.getTime() / 1000;
            return ts;
        } catch (ParseException e) {
            return 0;
        }
    }


    public ArrayList<StockBase> getData() throws SQLException {
        Connection connection = JdbcUtil.getConnection();
        Statement statement = connection.createStatement();
        String sql = "select Market_Symbol,Exchange_Symbol,Prod_name from stock where  Market_value >= '50000000000'";
        ResultSet rs = statement.executeQuery(sql);
        ArrayList<StockBase> stockBases = new ArrayList<>();
        while (rs.next()) {
            StockBase stockBase = new StockBase();
            stockBase.setPre(rs.getString(1));
            stockBase.setFix(rs.getString(2));
            stockBase.setName(rs.getString(3));
            stockBases.add(stockBase);
        }
        connection.close();
        return stockBases;
    }

    public ResponseData parse(String json) {
        ResponseData responseData = JSONObject.parseObject(json, ResponseData.class);
        return responseData;
    }

    public boolean cal(Double b1, Double b2) {
        //b1现价，b2为60k线价钱
        Double b = b2 - b1;
        if (b < 0 || b < b1 * 0.1) {
            return false;
        }
        return true;
    }

    public void sort(ArrayList<KlineData> data) {
        Collections.sort(data, new Comparator<KlineData>() {
            @Override
            public int compare(KlineData o1, KlineData o2) {
                return Integer.parseInt(o2.getTradingDay()) - Integer.parseInt(o1.getTradingDay());
            }
        });
    }

    //获取60日k线价格
    public Double getSixValue(ArrayList<KlineData> data) {
        sort(data);
        double sum = 0.0;
        for (int i = 0; i < 60; i++) {
            KlineData klineData = data.get(i);
            sum += Double.parseDouble(klineData.getClose());
        }
        double avg = sum / 60;
        return Double.parseDouble(String.format("%.2f", avg));
    }

    //获取20日k线价格
    public Double getTowValue(ArrayList<KlineData> data) {
        sort(data);
        double sum = 0.0;
        for (int i = 0; i < 20; i++) {
            KlineData klineData = data.get(i);
            sum += Double.parseDouble(klineData.getClose());
        }
        double avg = sum / 20;
        return Double.parseDouble(String.format("%.2f", avg));
    }

    public <T> List<List<T>> fixedGrouping2(List<T> source, int n) {

        if (null == source || source.size() == 0 || n <= 0)
            return null;
        List<List<T>> result = new ArrayList<List<T>>();
        int remainder = source.size() % n;
        int size = (source.size() / n);
        for (int i = 0; i < size; i++) {
            List<T> subset = null;
            subset = source.subList(i * n, (i + 1) * n);
            result.add(subset);
        }
        if (remainder > 0) {
            List<T> subset = null;
            subset = source.subList(size * n, size * n + remainder);
            result.add(subset);
        }
        return result;
    }

}
